package org.breathe.datastruct.impl;

import org.breathe.datastruct.RedisBytes;
import org.breathe.datastruct.RedisData;
import org.breathe.protocal.Resp;
import org.breathe.protocal.decode.BulkString;

import java.util.*;

/**
 * @author: breathe
 * @createTime: 2025-05-13
 */
public class RedisList implements RedisData {
    private volatile long timeout = -1;
    private LinkedList<RedisBytes> list;
    public RedisList() {
        this.list = new LinkedList<>();
    }

    @Override
    public long timeout() {
        return timeout;
    }

    @Override
    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }

    @Override
    public List<Resp> convertToResp() {
        List<Resp> result = new ArrayList<>();
        for (RedisBytes value : list) {
            result.add(new BulkString(value));
        }
        return result;
    }

    public int size() {
        return list.size();
    }
    public void lPush(RedisBytes... values) {
        Arrays.stream(values).forEach(list::addFirst);
    }
    public void rPush(RedisBytes... values) {
        Arrays.stream(values).forEach(list::addLast);
    }
    public RedisBytes lPop() {
        return list.pollFirst();
    }
    public RedisBytes rPop() {
        return list.pollLast();
    }
    public List<RedisBytes> lRange(int start, int stop) {
        int size = list.size();
        start = Math.max(0, start);
        stop = Math.min(size - 1, stop);
        if (start <= stop) {
            return list.subList(start, stop + 1);
        }
        return Collections.emptyList();
    }
    public List<RedisBytes> rRange(int start, int stop) {
        int size = list.size();
        start = Math.min(size - 1, size - 1 - start);
        stop = Math.max(0, size - 1 - stop);
        if (start >= stop) {
            return list.subList(stop, start + 1);
        }
        return Collections.emptyList();
    }
    public int remove(RedisBytes key) {
        int count = 0;
        while (list.remove(key)) {
            count ++;
        }
        return count;
    }

    public RedisBytes[] getAll() {
        RedisBytes[] result = new RedisBytes[list.size()];
        for (int i = 0; i < list.size(); i ++) {
            result[i] = list.get(i);
        }
        return result;
    }
}
